/*
 * @Descripttion : tabs
 * @Author       : QianFox Team
 * @Date         : 2022-04-14 17:44:31
 * @LastEditors  : QianFox Team
 * @LastEditTime : 2024-08-07 09:26:52
 */

import { _typeOf } from './common/utils';
import { observer } from './common/observer';

function Tabs() {
    this.TABS = '.foxui-tabs';
    this.LINETABS = '.foxui-tabs.foxui-type-line';
    this.ACTIVEITEM = '.foxui-tabs-item.is-active';
    this.HEADER = '.foxui-tabs-header';
    this.CONTENT = '.foxui-tabs-content';
    this.PANE = '.foxui-tabs-pane';
    this.ITEM = '.foxui-tabs-item';
    this.BAR = '.foxui-tabs__active-bar';
}

Tabs.prototype._init = function () {
    this._initTabs();
    this._bindToggleTab();
};

/**
 * @description: 初始化Tabs （页面初始化时，初始化全部已存在的Tabs）
 * @param {*}
 * @return {*}
 * @Date: 2022-04-15 08:49:58
 */
Tabs.prototype._initTabs = function () {
    let that = this;

    // 初始化 foxui-tabs
    $(this.TABS).each(function () {
        that.init(this);
    });
};

/**
 * @description: 初始化 Tabs （后追加的Slider，单项）
 * @param {*} container                  容器节点 -> class | id | jQuery节点对象
 * @return {*}
 * @Date: 2022-04-15 09:42:58
 */
Tabs.prototype.init = function (container) {
    let $container = $(container),
        isLineTabs = $container.is('.foxui-type-line');

    // 设置 pane 显示
    this._setPane($container);
    // 如果为 foxui-tabs-line，则设置 bar
    if (isLineTabs) {
        this._setBar($container);
    }
};

/**
 * @description: 设置 pane 面板的显示
 * @param {*} container          容器节点的 jQuery 对象
 * @return {*}
 * @Date: 2022-04-15 09:21:34
 */
Tabs.prototype._setPane = function ($container) {
    let $activeItem = $container.children(this.HEADER).children(this.ACTIVEITEM),
        $item = $container.children(this.HEADER).children(this.ITEM),
        $pane = $container.children(this.CONTENT).children(this.PANE);

    // 显示内容
    let index = $item.index($activeItem);
    $pane.hide();
    $pane.eq(index).show();
};

/**
 * @description: 设置 指示条 bar
 * @param {*} container         容器节点的 jQuery 对象
 * @return {*}
 * @Date: 2022-04-15 09:15:41
 */
Tabs.prototype._setBar = function ($container) {
    let $activeItem = $container.children(this.HEADER).children(this.ACTIVEITEM),
        $header = $container.children(this.HEADER),
        $bar = $container.children(this.HEADER).children(this.BAR),
        len = $bar.length,
        isRight = $container.is('.foxui-position-right'),
        // 计算 bar 的宽度 （ width + padding-left + padding + right）
        barWidth = $activeItem.width(),
        barPaddingLeft = $activeItem.css('padding-left'),
        barPaddingRight = $activeItem.css('padding-right'),
        barCountWidth = barWidth + parseInt(barPaddingLeft) + parseInt(barPaddingRight),
        // 计算 bar 的 X 坐标
        activeLeft = $activeItem.offset().left,
        tabsLeft = $container.offset().left,
        tabsPaddingLeft = $header.css('padding-left'),
        barCountX = 0;

    if (isRight) {
        let index = $activeItem.index() + 1,
            $items = $container.children(this.HEADER).children(this.ITEM),
            tabLen = $items.length,
            widths = 0;
        for (let len = tabLen; len > index; len--) {
            widths += $($items[len - 1]).outerWidth();
        }
        barCountX = -widths;
    } else {
        barCountX = activeLeft - tabsLeft - parseInt(tabsPaddingLeft);
    }

    // 设置 ban 宽度与位置
    if (len > 0) {
        $bar.css({
            width: barCountWidth + 'px',
            transform: 'translateX(' + barCountX + 'px)',
        });
    } else {
        $header.append(
            `<div class="foxui-tabs__active-bar" style="width:${barCountWidth}px; transform:translateX(${barCountX}px)"></div>`
        );
    }
};

/**
 * @description: 绑定切换tab
 * @param {*}
 * @return {*}
 * @Date: 2022-04-15 10:04:29
 */
Tabs.prototype._bindToggleTab = function () {
    let that = this;
    $(document).on('click', this.ITEM, function () {
        if (!$(this).is('.is-active')) {
            let $this = $(this),
                $container = $this.closest(that.TABS),
                $active = $container.children(this.HEADER).children(that.ACTIVEITEM),
                index = $this.index();

            // 设置当前项为激活项（必须放上面，否则切换后显示内容与bar位置不对）
            $active.removeClass('is-active');
            $this.addClass('is-active');
            // 设置 pane 显示、 bar 位置 (必须放下面，否则切换后显示内容与bar位置不对)
            that.init($container);
            // 发布消息(内部)
            observer._publiced('tabs', {
                index,
                id: $container.attr('id') ? $container.attr('id') : '',
            });
            // 发布消息
            let subid = $(this).closest(that.TABS).attr('data-subid');
            if (subid) observer._publiced('custom', index, subid, 'change');
        }
    });
};

/**
 * @description: 添加订阅者(内部) --> 改变时
 * @param {*} callback
 * @return {*}
 * @Date: 2022-04-18 14:52:28
 */
Tabs.prototype._onChange = function (callback) {
    observer._subscribe('tabs', callback);
};

/**
 * @description: 添加订阅者 --> 改变时
 * @param {*} subid
 * @param {*} callback
 * @return {*}
 * @Date: 2024-08-06 16:37:35
 */
Tabs.prototype.onChange = function (subid, callback) {
    if (subid && _typeOf(callback) === 'function') {
        observer._subscribe('custom', callback, subid, 'change');
    }
};

/**
 * @description: 取消订阅(内部) --> 改变时
 * @param {*} callback
 * @return {*}
 * @Date: 2022-04-18 14:54:43
 */
Tabs.prototype._unChange = function (callback) {
    observer._unsubscribe('tabs', callback);
};

/**
 * @description: 取消订阅 --> 改变时
 * @param {*} subid
 * @return {*}
 * @Date: 2024-08-06 16:37:08
 */
Tabs.prototype.unChange = function (subid) {
    if (subid) observer._unsubscribe('custom', null, subid, 'change');
};

let tabs = new Tabs();

export { tabs };
